# Classical binary propositional calculus, defined in mvl-toolkit by Koen Lefever 2009-2010, GPL v.3 licensed
# False & True are Python's built-in Boolean values.

from Logic import *

class PC(Logic):
    """Classical binary propositional logic"""
    def __init__(self, truth_values_list = [False, True], designated_values_list = [True]):
        if not len(truth_values_list) == 2:
            raise ValueError('PC is a binary logic, please provide two truth values.')
        if not len(designated_values_list) == 1:
            raise ValueError('Please provide exactly one designated value for PC.')
        Logic.__init__(self, truth_values_list, designated_values_list)

    def FALSE(self, P, Q, use_aliases = True):
        return self.operator(0, P, Q, use_aliases)               # always returns 'F', whatever the values of P & Q are

    def AND(self, P, Q, use_aliases = True):
        return self.operator(1, P, Q, use_aliases)

    def P(self, P, Q, use_aliases = True):
        return self.operator(3, P, Q, use_aliases)               # always return value of P, whatever Q is

    def Q(self, P, Q, use_aliases = True):
        return self.operator(5, P, Q, use_aliases)               # always return value of Q, whatever P is

    def XOR(self, P,Q, use_aliases = True):
        return self.operator(6, P, Q, use_aliases)               # exclusive or (aut)

    def OR(self, P, Q, use_aliases = True):
        return self.operator(7, P , Q, use_aliases)              # inclusive or (vel)

    def NOR(self, P, Q, use_aliases = True):
        return self.operator(8, P, Q, use_aliases)               # dual of the Sheffer stroke

    def IFF(self, P, Q, use_aliases = True):
        return self.operator(9, P, Q, use_aliases)               # if and only if

    def NOT_Q(self, P, Q, use_aliases = True):
        return self.operator(10, P, Q, use_aliases)              # always returns NOT Q, whatever the value of P is

    def IF_Q_THEN_P(self, P, Q, use_aliases = True):
        return self.operator(11, P, Q, use_aliases)

    def NOT_P(self, P, Q, use_aliases = True):
        return self.operator(12, P, Q, use_aliases)              # always returns NOT P, whatever the value of P is

    def IF_THEN(self, P, Q, use_aliases = True):
        return self.operator(13, P, Q, use_aliases)

    def NAND(self, P, Q, use_aliases = True):
        return self.operator(14, P, Q, use_aliases)              # Sheffer stroke

    def TRUE(self, P, Q, use_aliases = True):
        return self.operator(15, P, Q, use_aliases)              # always returns 'T', whatever the values of P & Q are

    def NOT(self, P, use_aliases = True):
        return self.not_p(P, True, use_aliases)                  # unary NOT defined as a binary operator
